這一篇是我很糾結的,但是總是要來面對。
定義基本或結構化數據類型
從 Genero 2.50開始,原先的 DEFINE定義區塊,開始支援 TYPE。這是可以結構化定義數組(RECORD)。然後在需要的地方調用。
PRIVATE TYPE type_abc RECORD
col01 VARCHAR(100),
col02 LIKE table_A.col02
END RECORD
PUBLIC TYPE type_desk RECORD #桌子
length INT, #長
height INT, #高
shape RECORD
drawer INT #抽屜數
END RECORD
END RECORD
DEFINE desk1 type_desk #命名一個 desk1
利用這樣的結構,可以在程式的任何地方輕鬆地生成結構,調整的時候也可避免到處調整。最前端的 PUBLIC/PRIVATE則是標示了:當這支4GL被 IMPORT的時候,能否在引用作業中直接調用TYPE
當 TYPE到 Genero 3.20以後的版本,開始支援 ATTRIBUTES 屬性配置,可以搭配 REST WEB SERVICE的配置,這部分暫時略過不提
函式名稱定義。
其實 FUNCTION 從 Genero 3.0開始不斷的在增加新語法,除了原先單純定義之外還有下列的新語法(Genero3.X以後支持,舊版本無法編譯此新語法):
語法1
PUBLIC FUNCTION func_abc( input_var )
透過這樣的語法,因為是 PUBLIC 的,所以可以在任何 42m 調動此 function_abc,且傳入參數 input_var
語法2
PUBLIC FUNCTION func_abc( input_var INT, comm_var INT INOUT ) RETURNS (INT, INT)
從Genero 3.20開始,在設定傳入參數的時候可以一併指定型態,這樣可以減少DEFINE的量。但此處不可使用 LIKE的方式指定。INOUT標定該參數同時傳入傳出,使用 CALL BY REFERENCE的做法。
最後的 RETURNS (**注意不是RETURN 也不是 RETURNING **),則是標定回傳應為兩個 INT,做編譯時的型別檢查用。(單一個的時候,不需要加上括號)
語法3則直接上範例進行解說
TYPE Rectangle RECORD #定義一個矩形
height, width DOUBLE PRECISION #存在長、寬 雙精度數值
END RECORD
#下面的 FUNCTION在定義 物件(TYPE)所需要的 "方法"
# 物件 r 的 TYPE為 Rectangle
# 方法:算面積 回傳 面積的雙精度數值
FUNCTION (r Rectangle) area() RETURNS DOUBLE PRECISION
RETURN r.height * r.width #算法是長 x 寬
END FUNCTION
所以 TYPE可以是一個物件定義,透過 FUNCTION 綁上該物件可操作的方法,接著就可以操作為
DEFINE a Rectangle
LET a.height = 10
LET a.width = 20
DISPLAY a.area() #出現 200
此處需要特別注意,『變數名稱』和『方法名稱』不可以一樣,否則會出現 -8427 的錯誤
| Method and field names must be different. Type rectangle.Rectangle has field width.
| See error number -8427.
然後 FUNCTION 後方的 RETURNS 一定要標註(沒回傳也要標註),否則會出現 -8431的錯誤
| A method without return type (RETURNS) can not return values.
| See error number -8431.
** GENERO 3.20以後版本提供 **
變數可以透過數組(RECORD),預先定義出結構(TYPE):那一堆類似的方法(METHOD)可以預先定義出結構嗎?那叫做什麼?
對,可以的,那就叫做 INTERFACE。
接續上一個四邊形(Rectangle)的範例進行
TYPE Shape INTERFACE #結構化一個"介面"
area() RETURNS FLOAT, #內含兩種方法
kind() RETURNS STRING
END INTERFACE
準備好之後,就可以使用了:
DEFINE r Rectangle = ( height:10, width:20 ) #定義順便直接將數值帶入
DEFINE v1 Shape #取用 Shape 這個方法集
LET v1 = r #這個 INTERFACE 選用的是 r (Rectangle)
DISPLAY v1.area() #直接調動 INTERFACE內的 .area() 方法
對的,為了適應物件的方法,DEFINE可以直接將需要的元素資料在 DEFINE過程中直接放入。
有沒有開始有點不認識 FGL了?為了能跟物件體系有更好的整合,也保有傳統 4GL相容性,FourJs團隊找出這樣的方式進行物件化的操作。接下來還有更多的新變化,再請各位期待。